package com.zzr.demo.redis.service.impl;

import com.zzr.demo.redis.service.TimeLineService;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.startup.CopyParentClassLoaderRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author: xiaomi
 * @date: 2021/10/9
 * @description: 博客时间线
 */
@Service
@Slf4j
public class BlogTimeLineServiceImpl implements TimeLineService {

    final String TIME_LINE_KEY = "time::line";
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean addItem(String name, int score) {
        ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
        Boolean add = opsForZSet.add(TIME_LINE_KEY, name, score);
        log.info("add name {},score {}", name, score);
        return add;
    }

    @Override
    public long size() {
        ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
        Long size = opsForZSet.size(TIME_LINE_KEY);
        log.info("size:{}", size);
        return size;
    }

    /**
     * 使用 ZRANGE
     *
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public List<String> list(int pageNum, int pageSize) {
        //start 的计算和 offset 相同
        int start = (pageNum - 1) * pageSize;
        int end = pageNum * pageSize - 1;
        ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<String>> typedTuples = opsForZSet.rangeWithScores(TIME_LINE_KEY, start, end);
        List<String> list = new ArrayList<>();
        for (ZSetOperations.TypedTuple<String> item :
                typedTuples) {
            list.add(item.getValue() + ":" + item.getScore());
        }
        log.info("list:{}", list);
        return list;
    }

    @Override
    public List<String> listByScore(int pageNum, int pageSize, int min, int max) {
        //start 的计算和 offset 相同
        int offset = (pageNum - 1) * pageSize;
        int count = pageSize;
        ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
        Set<ZSetOperations.TypedTuple<String>> typedTuples = opsForZSet.rangeByScoreWithScores(TIME_LINE_KEY, min, max, offset, count);
        List<String> list = new ArrayList<>();
        for (ZSetOperations.TypedTuple<String> item :
                typedTuples) {
            list.add(item.getValue() + ":" + item.getScore());
        }
        log.info("list:{}", list);
        return list;
    }
}
